package main

import "fmt"

func main() {
	/*
		1.按照类型来分：
			基本类型：int, float, string, bool
			复合类型：array, slice, map, struct, pointer, function, channel
		2.按照特点来分：
			值类型：int, float, string, bool, array
				传递的是数据脚本
			引用类型：slice
				传递的地址，多个变量指向了同一快内存地址

		所以，切片是引用类型的数据，存储了底层数组的引用

		3.切片不能直接进行比较：
		（1）判断切片是否为空，请始终使用 len(s) == 0 来判断，而不应该使用 s == nil 来判断
				len(s) == 0 ———————————————✔——————————————> 切片为 空
				   s == nil ———————————————✘——————————————> 切片为 空

		（2）切片之间是不能比较的，我们不能使用 == 操作符来判断两个切片是否含有全部相等元素。
			切片唯一合法的比较操作是和 nil 比较。
			一个 nil 值的切片并没有底层数组，一个 nil 值的切片的长度和容量都是 0.
			但是，我们不能说一个长度和容量都是 0 的切片一定是 nil。
			s == nil ——————————✔——————————> len(s) == 0 && cap(s) == 0
			len(s) == 0 && cap(s) == 0 ——————————✘——————————> s == nil

		4.append() 方法为切片添加元素（补充）
			通过 var 声明的零值切片可以在 append() 函数直接使用，无需初始化
	*/

	//1.数组：值类型

	//2.切片：引用类型
	ss1 := []int{1, 2, 3, 4}
	ss2 := ss1
	ss1[0] = 100
	fmt.Println(ss1, ss2) // [100 2 3 4] [100 2 3 4]

	fmt.Println("--------------------------------------------")

	var s1 []int         //len(s1) = 0; cap(s1) = 0; s1 == nil
	s2 := []int{}        //len(s2) = 0; cap(s2) = 0; s2 != nil
	s3 := make([]int, 0) //len(s3) = 0; cap(s3) = 0; s3 != nil
	fmt.Println(s1, s2, s3)

	fmt.Println("---------------------------------------------")

	//通过var声明的零值切片可以在append()函数直接使用，无需初始化。
	var sss []int
	sss = append(sss, 1, 2, 3)

	//没有必要像下面的代码一样初始化一个切片再传入 append（）
	sss1 := []int{} //没有必要初始化
	sss1 = append(sss1, 1, 2, 3, 4)

	var sss2 = make([]int, 0) //没有必要初始化
	sss2 = append(sss2, 1, 2, 3, 4)
}
